package com.kancy.spring.boot.drools.service;

import com.kancy.spring.boot.drools.utils.KieUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.kie.api.runtime.KieSession;

import java.util.Objects;

/**
 * <p>
 * LocalDroolsRuleEngine
 * <p>
 *
 * @author: kancy
 * @date: 2020/4/3 19:32
 **/

public class LocalDroolsRuleEngine {

    private String defaultSessionName;

    public LocalDroolsRuleEngine() {
    }

    public LocalDroolsRuleEngine(String sessionName) {
        this.defaultSessionName = sessionName;
    }

    public Session session(){
        return new Session(defaultSessionName);
    }

    public Session session(String sessionName){
        return new Session(sessionName);
    }

    /**
     * 调用规则引擎
     * @param session
     * @param facts
     */
    public void call(String session, Object ... facts){
        Session sessionBuilder = session(session);
        // set fact object
        if (ArrayUtils.isNotEmpty(facts)){
            for (Object fact : facts) {
                sessionBuilder.insert(fact);
            }
        }
        sessionBuilder.call();
    }

    public static class Session {

        private Session() {
        }

        private KieSession kieSession;

        public Session(String sessionName) {
            if (Objects.isNull(sessionName)){
                this.kieSession = KieUtils.getKieClasspathContainer().newKieSession();
            }else {
                this.kieSession = KieUtils.getKieClasspathContainer().newKieSession(sessionName);
            }
        }

        public Session setGlobal(String identifier, Object globalObject){
            kieSession.setGlobal(identifier, globalObject);
            return this;
        }

        public Session insert(Object fact){
            kieSession.insert(fact);
            return this;
        }

        public void call(){
            try {
                kieSession.fireAllRules();
            } finally {
                closeKieSession(kieSession);
            }
        }
    }

    private static void closeKieSession(KieSession kieSession) {
        if (Objects.nonNull(kieSession)) {
            kieSession.dispose();
        }
    }
}
